'use client'; // 必须标记为客户端组件

import { Suspense, useMemo, useRef } from 'react';
import { Canvas } from '@react-three/fiber';
import { Center, Preload, useGLTF } from '@react-three/drei';
import * as THREE from 'three';
import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';

useGLTF.preload('/bicycle.glb');

function Model() {
  const { scene } = useGLTF('/bicycle.glb') as unknown as GLTF;
  const materialSnapshots = useMemo(
    () =>
      new WeakMap<
        THREE.Material,
        { color?: THREE.Color; emissive?: THREE.Color }
      >(),
    []
  );
  const highlighted = useRef<THREE.Material[] | null>(null);

  const ensureSnapshots = (mats: THREE.Material[]) => {
    mats.forEach((mat) => {
      if (!materialSnapshots.has(mat)) {
        materialSnapshots.set(mat, {
          color: mat.color?.clone?.(),
          emissive: mat.emissive?.clone?.(),
        });
      }
    });
  };

  const restore = (mats: THREE.Material[]) => {
    mats.forEach((mat) => {
      const original = materialSnapshots.get(mat);
      if (!original) return;
      if (mat.color && original.color) mat.color.copy(original.color);
      if (mat.emissive && original.emissive)
        mat.emissive.copy(original.emissive);
    });
  };

  const highlight = (mats: THREE.Material[]) => {
    mats.forEach((mat) => {
      if (mat.color) mat.color.set('#ff9900');
      if (mat.emissive) mat.emissive.set('#ffcc66');
    });
  };

  const handleHover = (mats: THREE.Material[]) => {
    if (highlighted.current) restore(highlighted.current);
    ensureSnapshots(mats);
    highlight(mats);
    highlighted.current = mats;
  };

  const handleOut = () => {
    if (!highlighted.current) return;
    restore(highlighted.current);
    highlighted.current = null;
  };

  return (
    <group
      onPointerOver={(e) => {
        e.stopPropagation();
        const target = (e as any).object;
        if (!target || !target.material) return;
        const mats = Array.isArray(target.material)
          ? (target.material as THREE.Material[])
          : [target.material as THREE.Material];
        handleHover(mats);
      }}
      onPointerOut={handleOut}
    >
      <primitive object={scene} />
    </group>
  );
}

export default function ModelViewer() {
  return (
    <div style={{ width: '100%', height: '500px', background: 'transparent' }}>
      <Canvas
        camera={{ position: [0, 0, 14], fov: 40 }}
        gl={{ alpha: true, antialias: true }}
        style={{ background: 'transparent' }}
      >
        <ambientLight intensity={0.5} />
        <directionalLight position={[10, 10, 10]} intensity={1} />
        <Suspense fallback={null /* or a loader component */}>
          <Center>
            <Model />
          </Center>
          <Preload all />
        </Suspense>
      </Canvas>
    </div>
  );
}
